package net.xxcxcxcx.xc_enhancedmob.skills;

import net.minecraft.entity.mob.MobEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.world.World;
import net.xxcxcxcx.xc_enhancedmob.component.EnhancedBaseComponent;
import net.xxcxcxcx.xc_enhancedmob.skills.basics.individual.breakout.*;
import net.xxcxcxcx.xc_enhancedmob.skills.basics.individual.common.*;
import net.xxcxcxcx.xc_enhancedmob.skills.basics.individual.doubleedged.*;
import net.xxcxcxcx.xc_enhancedmob.skills.basics.individual.mystery.*;
import net.xxcxcxcx.xc_enhancedmob.skills.basics.individual.rare.*;
import net.xxcxcxcx.xc_enhancedmob.skills.basics.testSkill;
import net.xxcxcxcx.xc_enhancedmob.skills.environment.BaseEnvironmentSkill;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;

import static net.xxcxcxcx.xc_enhancedmob.EnhancedMobMod.StartTest;

public class SkillHelper {
    public static List<SkillMaker> AllSkills = new ArrayList<>();
    public static Map<String, Class> getSkills;
    public static Skill[][] EnvironmentSkill = new Skill[10][10];

    public static void Init() {
        AllSkillsInit();
        AllEnvironmentSkills();
        getSkills = AllSkills.stream().collect(Collectors.toMap(SkillMaker::getName, SkillMaker::getaClass));
    }

    public static Class getSkillClass(String s) {
        return getSkills.get(s);
    }

    public static void AllSkillsInit() {
        AllSkills.add(new SkillMaker(testSkill.class, testSkill.class.getSimpleName()));
        //Common Skills
        AllSkills.add(new SkillMaker(AlchemySkill.class, AlchemySkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(BlindnessSkill.class, BlindnessSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(FireballSkill.class, FireballSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(FortitudeSkill.class, FortitudeSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(HungerSkill.class, HungerSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(IronSkinSkill.class, IronSkinSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(MachampSkill.class, MachampSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(MedicalTreatmentSkill.class, MedicalTreatmentSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(PoisoningSkill.class, PoisoningSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(QuicknessSkill.class, QuicknessSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(RemoteSkill.class, RemoteSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(SelfdetonationSkill.class, SelfdetonationSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(ShadowSkill.class, ShadowSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(SlowSkill.class, SlowSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(ThornsSkill.class, ThornsSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(TraceballSkill.class, TraceballSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(VitalitySkill.class, VitalitySkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(WeaknessSkill.class, WeaknessSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(WitherSkill.class, WitherSkill.class.getSimpleName()));
        //Rare Skills
        AllSkills.add(new SkillMaker(AcidSkill.class, AcidSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(AdaptSkill.class, AdaptSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(ArrowRainSkill.class, ArrowRainSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(AttractiveSkill.class, AttractiveSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(BlockSkill.class, BlockSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(CapriceSkill.class, CapriceSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(CorrodeSkill.class, CorrodeSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(CriticalSkill.class, CriticalSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(DashSkill.class, DashSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(DispelSkill.class, DispelSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(DrugSkill.class,DrugSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(EavdeSkill.class, EavdeSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(FadeSkill.class, FadeSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(GravitySkill.class, GravitySkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(HoldSkill.class, HoldSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(HurricaneSkill.class, HurricaneSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(IterationSkill.class, IterationSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(MedicationSkill.class,MedicationSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(MeteorSkill.class, MeteorSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(ParalysisSkill.class, ParalysisSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(ParrySkill.class, ParrySkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(PhoenixSkill.class, PhoenixSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(PushSkill.class,PushSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(RadiateSkill.class,RadiateSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(ReboundSkill.class, ReboundSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(RebuildSkill.class, RebuildSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(RestrictionSkill.class, RestrictionSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(RocketSkill.class,RocketSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(StealthSkill.class, StealthSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(StressSkill.class, StressSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(TraumaSkill.class, TraumaSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(VampireSkill.class, VampireSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(WeavingWebSkill.class, WeavingWebSkill.class.getSimpleName()));
        //Mystery Skills
        AllSkills.add(new SkillMaker(ArmorShieldSkill.class, ArmorShieldSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(AssassinateSkill.class,AssassinateSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(ChainSkill.class,ChainSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(ConversionSkill.class,ConversionSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(Delaying.class, Delaying.class.getSimpleName()));
        AllSkills.add(new SkillMaker(EmergencyTreatmentSkill.class,EmergencyTreatmentSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(ExecutionSkill.class, ExecutionSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(FallSkill.class,FallSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(MirrorSkill.class, MirrorSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(PunctureSkill.class, PunctureSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(RebirthSkill.class,RebirthSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(RecklessnessSkill.class, RecklessnessSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(ShieldSkill.class, ShieldSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(SnipeSkill.class,SnipeSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(ThunderSkill.class,ThunderSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(VisciditySkill.class,VisciditySkill.class.getSimpleName()));
        //Double edged skills
        AllSkills.add(new SkillMaker(ConnectionSkill.class,ConnectionSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(GlassSkill.class,GlassSkill.class.getSimpleName()));
        //Break out skills
        AllSkills.add(new SkillMaker(LastwordSkill.class, LastwordSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(BloodthirstySkill.class,BloodthirstySkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(StillnessSkill.class,StillnessSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(HypertherapySkill.class,HypertherapySkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(RageSkill.class,RageSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(ForbidHealSkill.class,ForbidHealSkill.class.getSimpleName()));
        AllSkills.add(new SkillMaker(UnyieldingSkill.class,UnyieldingSkill.class.getSimpleName()));
    }

    public static void AllEnvironmentSkills() {
        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                EnvironmentSkill[i][j] = null;
            }
        }
        AllSkills.add(new SkillMaker(BaseEnvironmentSkill.class, BaseEnvironmentSkill.class.getSimpleName()));
    }

    public static List<Skill> makeSkillsfromNbt(NbtCompound nbtCompound) {
        List<Skill> list = new ArrayList<>();
        for (String s : nbtCompound.getKeys()) {
            AllSkills.stream().filter((skillMaker -> skillMaker.getName().equals(s))).findFirst()
                    .ifPresent(skillMaker -> {
                        try {
                            Constructor constructor = skillMaker.getaClass().getConstructor(NbtCompound.class);
                            list.add((Skill) constructor.newInstance(nbtCompound.get(s)));
                        } catch (NoSuchMethodException | IllegalAccessException | InstantiationException |
                                 InvocationTargetException e) {
                            throw new RuntimeException(e);
                        }
                    });
        }
        return list;
    }

    public static void randomskills(EnhancedBaseComponent enhancedBaseComponent) {
        if (StartTest) {
            Random random = new Random();
            List<Skill> list = new ArrayList<>();
            list.add(new ForbidHealSkill(random.nextInt(2) + 1));
            list.add(new UnyieldingSkill(random.nextInt(2) + 1));
            enhancedBaseComponent.setSkills(list);
        }
    }

    public static void randomenvironmentskills(EnhancedBaseComponent enhancedBaseComponent) {
        if (StartTest) {
            Random random = new Random();
            Skill skill = new BaseEnvironmentSkill();
            enhancedBaseComponent.setEnvironment(skill);
            return;
        }
        MobEntity entity = enhancedBaseComponent.getMobEntity();
        if (entity.world.getRegistryKey() == World.OVERWORLD) {
            float t = entity.world.getBiome(entity.getBlockPos()).getTemperature() + 1;
            float d = entity.world.getBiome(entity.getBlockPos()).getDownfall();
            int n = 0, m = 0;
            while (d > 0.2) {
                d -= 0.2;
                n++;
            }
            while (t > 0.5) {
                t -= 0.5;
                m++;
            }
            if (n >= 10 || m >= 10 || EnvironmentSkill[n][m] == null) {
                enhancedBaseComponent.setEnvironment(new BaseEnvironmentSkill());
            } else enhancedBaseComponent.setEnvironment(EnvironmentSkill[n][m]);
        } else if (entity.world.getRegistryKey() == World.NETHER) {
            enhancedBaseComponent.setEnvironment(new BaseEnvironmentSkill());
        } else if (entity.world.getRegistryKey() == World.END) {
            enhancedBaseComponent.setEnvironment(new BaseEnvironmentSkill());
        } else {
            enhancedBaseComponent.setEnvironment(new BaseEnvironmentSkill());
        }
    }

    public static class SkillMaker {
        private final Class aClass;
        private final String name;

        public SkillMaker(Class a, String n) {
            aClass = a;
            name = n;
        }

        public String getName() {
            return name;
        }

        public Class getaClass() {
            return aClass;
        }
    }
}
